/*
 * PanelConsulta.java
 *
 * Created on 17 de septiembre de 2008, 22:20
 */
package gui;

import controladores.ControladorGeneral;
import controladores.IControladorObserver;
import java.awt.Cursor;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.File;
import java.util.List;
import java.util.TreeMap;
import javax.swing.DefaultListModel;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.filechooser.FileFilter;
import tesauro.IHashCodeStrategy;

/**
 *
 * @author  demian
 */
public class PanelGeneral extends javax.swing.JPanel implements IControladorObserver, WindowListener {
    JFrame ayudaFrame;
    boolean administradorHabilitado;
    boolean diccionarioCambio;
    ControladorGeneral controlador;
    DefaultListModel sinonimosListModel;
    static final AlgoritmoHash algoritmosHash[] = {new AlgoritmoHash("Nativo Java", "tesauro.NativeStringHashCode"),
                                                                                  new AlgoritmoHash("DJB", "tesauro.DJBStringHashCode"),
                                                                                  new AlgoritmoHash("ELF", "tesauro.ELFStringHashCode"),
                                                                                  new AlgoritmoHash("TSB", "tesauro.TSBStringHashCode")};

    /**
     * Para meter como items en el comobo box de eleccion de algoritmo hash. Asi tendre que nombre
     * es el nombre que se va a mostrar en el combobox y clase es el nombre de la clase que lo implementa.
     */
    static class AlgoritmoHash {
        String nombre;
        String clase;

        AlgoritmoHash(String nombre, String clase) {
            this.nombre = nombre;
            this.clase = clase;
        }

        public String toString() {
            return this.nombre;
        }
        
        public boolean equals(Object o) {
            if(o == null || !(o instanceof AlgoritmoHash)) {
                return false;
            }
            
            AlgoritmoHash oTmp = (AlgoritmoHash)o;
            return oTmp.nombre.endsWith(nombre) && oTmp.clase.endsWith(clase);
        }
    }

    /** Creates new form PanelConsulta */
    public PanelGeneral() {
        initComponents();
        controlador = new ControladorGeneral();
        controlador.setObserver(this);
        sinonimosListModel = new DefaultListModel();
        sinonimosListModel.addListDataListener(new ListDataListener() {
            public void intervalAdded(ListDataEvent evt) {
                DefaultListModel model = (DefaultListModel)evt.getSource();
                if(model.getSize() > 0 && administradorHabilitado) {
                    jButtonSinonimoAgregar.setEnabled(true);
                    jButtonSinonimoEliminar.setEnabled(true);
                }
            }

            public void intervalRemoved(ListDataEvent evt) {
                DefaultListModel model = (DefaultListModel)evt.getSource();
                if(model.getSize() == 0) {
                    jButtonSinonimoAgregar.setEnabled(false);
                    jButtonSinonimoEliminar.setEnabled(false);
                }
            }

            public void contentsChanged(ListDataEvent evt) {
                DefaultListModel model = (DefaultListModel)evt.getSource();
                if(model.getSize() > 0 && administradorHabilitado) {
                    jButtonSinonimoAgregar.setEnabled(true);
                    jButtonSinonimoEliminar.setEnabled(true);
                } else {
                    jButtonSinonimoAgregar.setEnabled(false);
                    jButtonSinonimoEliminar.setEnabled(false);                    
                }
            }            
        });
        
        jListSinonimos.setModel(sinonimosListModel);
        
        for (int i = 0; i < algoritmosHash.length; i++) {
            jComboBoxAlgoritmoHash.addItem(algoritmosHash[i]);
        }

        jButtonAbrirDiccionario.requestFocusInWindow();
    }
    
    private void agregarSinonimos(String palabra) {
        String sinonimosString = JOptionPane.showInputDialog(this, "Ingrese los sinonimos separados por comas.", "Agregar sinonimos a '"+ palabra +"'",
                                                                                                    JOptionPane.PLAIN_MESSAGE);
        if(sinonimosString == null) {
            return;                
        }

        if(!controlador.existePalabra(palabra)) {
            controlador.agregarPalabra(palabra, sinonimosString);
        } else {
            controlador.agregarSinonimo(palabra, sinonimosString);
        }
        
        diccionarioCambio = true;
        this.sinonimosListModel.removeAllElements();

        try {
            List<String> sinonimos = controlador.obtenerSinonimosDe(palabra);
            for (String sinonimo : sinonimos) {
                this.sinonimosListModel.addElement(sinonimo);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "Error no experado al obtener los sinonimos cargados.");
            resetPanel();
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        jTextFieldEstadoDiccionario = new javax.swing.JTextField();
        jPanelDatos = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jTextFieldPalabra = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jScrollPaneSinonimos = new javax.swing.JScrollPane();
        jListSinonimos = new javax.swing.JList();
        jButtonPalabraAgregar = new javax.swing.JButton();
        jButtonSinonimoAgregar = new javax.swing.JButton();
        jButtonPalabraEliminar = new javax.swing.JButton();
        jButtonSinonimoEliminar = new javax.swing.JButton();
        jPanelABM = new javax.swing.JPanel();
        jButtonNuevoDesdeArchivo = new javax.swing.JButton();
        jButtonAbrirDiccionario = new javax.swing.JButton();
        jButtonGuardarDiccionario = new javax.swing.JButton();
        jComboBoxAlgoritmoHash = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        jButtonAplicarAlgoritmo = new javax.swing.JButton();
        jButtonListar = new javax.swing.JButton();
        jButtonAdministrador = new javax.swing.JButton();
        jButtonAyuda = new javax.swing.JButton();
        jTextFieldTipoBusqueda = new javax.swing.JTextField();

        jTextFieldEstadoDiccionario.setEditable(false);
        jTextFieldEstadoDiccionario.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        jPanelDatos.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel1.setText("Palabra");

        jTextFieldPalabra.setEnabled(false);
        jTextFieldPalabra.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                jTextFieldPalabraKeyPressed(evt);
            }
        });

        jLabel2.setText("Sinonimos");

        jListSinonimos.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jListSinonimos.setEnabled(false);
        jScrollPaneSinonimos.setViewportView(jListSinonimos);

        jButtonPalabraAgregar.setText("+");
        jButtonPalabraAgregar.setEnabled(false);
        jButtonPalabraAgregar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonPalabraAgregarActionPerformed(evt);
            }
        });

        jButtonSinonimoAgregar.setText("+");
        jButtonSinonimoAgregar.setEnabled(false);
        jButtonSinonimoAgregar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSinonimoAgregarActionPerformed(evt);
            }
        });

        jButtonPalabraEliminar.setText("-");
        jButtonPalabraEliminar.setEnabled(false);
        jButtonPalabraEliminar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonPalabraEliminarActionPerformed(evt);
            }
        });

        jButtonSinonimoEliminar.setText("-");
        jButtonSinonimoEliminar.setEnabled(false);
        jButtonSinonimoEliminar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSinonimoEliminarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelDatosLayout = new javax.swing.GroupLayout(jPanelDatos);
        jPanelDatos.setLayout(jPanelDatosLayout);
        jPanelDatosLayout.setHorizontalGroup(
            jPanelDatosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelDatosLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelDatosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPaneSinonimos, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 367, Short.MAX_VALUE)
                    .addComponent(jTextFieldPalabra, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 367, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanelDatosLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 277, Short.MAX_VALUE)
                        .addComponent(jButtonPalabraAgregar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonPalabraEliminar))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanelDatosLayout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 258, Short.MAX_VALUE)
                        .addComponent(jButtonSinonimoAgregar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonSinonimoEliminar)))
                .addContainerGap())
        );
        jPanelDatosLayout.setVerticalGroup(
            jPanelDatosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelDatosLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelDatosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jButtonPalabraEliminar, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonPalabraAgregar, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldPalabra, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanelDatosLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jButtonSinonimoEliminar, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButtonSinonimoAgregar, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPaneSinonimos, javax.swing.GroupLayout.DEFAULT_SIZE, 276, Short.MAX_VALUE)
                .addContainerGap())
        );

        jPanelABM.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jButtonNuevoDesdeArchivo.setText("Nuevo desde Archivo");
        jButtonNuevoDesdeArchivo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonNuevoDesdeArchivoActionPerformed(evt);
            }
        });

        jButtonAbrirDiccionario.setText("Abrir Diccionario");
        jButtonAbrirDiccionario.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAbrirDiccionarioActionPerformed(evt);
            }
        });

        jButtonGuardarDiccionario.setText("Guardar Cambios");
        jButtonGuardarDiccionario.setEnabled(false);
        jButtonGuardarDiccionario.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonGuardarDiccionarioActionPerformed(evt);
            }
        });

        jComboBoxAlgoritmoHash.setEnabled(false);

        jLabel3.setText("Algoritmo de hash");

        jButtonAplicarAlgoritmo.setText("Aplicar Algoritmo");
        jButtonAplicarAlgoritmo.setEnabled(false);
        jButtonAplicarAlgoritmo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAplicarAlgoritmoActionPerformed(evt);
            }
        });

        jButtonListar.setText("Listar Diccionario");
        jButtonListar.setEnabled(false);
        jButtonListar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonListarDiccionarioActionPerformed(evt);
            }
        });

        jButtonAdministrador.setText("Habilitar Administrador");
        jButtonAdministrador.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAdministradorActionPerformed(evt);
            }
        });

        jButtonAyuda.setText("Ayuda");
        jButtonAyuda.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAyudaActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanelABMLayout = new javax.swing.GroupLayout(jPanelABM);
        jPanelABM.setLayout(jPanelABMLayout);
        jPanelABMLayout.setHorizontalGroup(
            jPanelABMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelABMLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanelABMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jButtonNuevoDesdeArchivo, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                    .addComponent(jButtonAbrirDiccionario, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                    .addComponent(jButtonGuardarDiccionario, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                    .addComponent(jLabel3)
                    .addComponent(jComboBoxAlgoritmoHash, 0, 225, Short.MAX_VALUE)
                    .addComponent(jButtonAplicarAlgoritmo, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                    .addComponent(jButtonListar, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                    .addComponent(jButtonAdministrador, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
                    .addComponent(jButtonAyuda, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE))
                .addContainerGap())
        );
        jPanelABMLayout.setVerticalGroup(
            jPanelABMLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelABMLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButtonNuevoDesdeArchivo)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonAbrirDiccionario)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonGuardarDiccionario)
                .addGap(18, 18, 18)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jComboBoxAlgoritmoHash, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonAplicarAlgoritmo)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonListar)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 89, Short.MAX_VALUE)
                .addComponent(jButtonAyuda)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jButtonAdministrador)
                .addContainerGap())
        );

        jTextFieldTipoBusqueda.setEditable(false);
        jTextFieldTipoBusqueda.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jPanelDatos, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanelABM, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jTextFieldEstadoDiccionario, javax.swing.GroupLayout.PREFERRED_SIZE, 522, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTextFieldTipoBusqueda)))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanelDatos, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanelABM, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldEstadoDiccionario, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jTextFieldTipoBusqueda, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents
     
	private void jButtonNuevoDesdeArchivoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonNuevoDesdeArchivoActionPerformed
            resetPanel();
            JFileChooser fileChooser = new JFileChooser(System.getProperty("user.dir") + File.separator + "data");
            fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
            fileChooser.setFileFilter(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    if(file.isDirectory()) {
                        return true;
                    }
                    
                    if(file.isFile() && file.getAbsolutePath().endsWith(".txt")) {
                        return true;
                    }

                    return false;
                }

                @Override
                public String getDescription() {
                    return "";
                }
            } );
            
            int result = fileChooser.showOpenDialog(this);

            if (result == JFileChooser.APPROVE_OPTION) {
                Cursor oldCursor = getCursor();
                
                try {
                    File archivo = fileChooser.getSelectedFile();
                    setCursor(new Cursor(Cursor.WAIT_CURSOR));
                    this.controlador.cargarDesdeArchivo(archivo);
                    setCursor(oldCursor);
                    JOptionPane.showMessageDialog(this, "Diccionario fue cargado correctamente.");

                    if(administradorHabilitado) {
                        this.jButtonPalabraAgregar.setEnabled(true);
                        this.jButtonPalabraEliminar.setEnabled(true);
                        this.jComboBoxAlgoritmoHash.setEnabled(true);
                        this.jButtonAplicarAlgoritmo.setEnabled(true);
                    }

                    this.jTextFieldPalabra.setEnabled(true);
                    this.jListSinonimos.setEnabled(true);
                    this.jButtonGuardarDiccionario.setEnabled(true);
                    this.jButtonListar.setEnabled(true);
                    this.jButtonAbrirDiccionario.setEnabled(true);
                    this.jTextFieldPalabra.requestFocusInWindow();
                } catch (Exception ex) {
                    setCursor(oldCursor);
                    String msg = ex.getMessage();
                    JOptionPane.showMessageDialog(this, "No se pudo cargar el diccionario." + (msg == null ? "" : "\nRazon: " + msg));
                    resetPanel();
                }
            }
    }//GEN-LAST:event_jButtonNuevoDesdeArchivoActionPerformed

    private void jTextFieldPalabraKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextFieldPalabraKeyPressed
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            JTextField textField = (JTextField) evt.getSource();
            String texto = textField.getText().trim();
            if (texto.isEmpty()) {
                sinonimosListModel.removeAllElements();
                return;
            } else {
                try {
                    if (!controlador.hayDiccionarioCargado()) {
                        JOptionPane.showMessageDialog(this, "No hay un diccionario cargado.");
                        sinonimosListModel.removeAllElements();
                        return;
                    }

                    if (!controlador.existePalabra(texto)) {
                        JOptionPane.showMessageDialog(this, "Palabra '" + texto + "' no cargada en el diccionario.");
                        sinonimosListModel.removeAllElements();
                        return;
                    }

                    long t0 = System.nanoTime();
                    List<String> sinonimos = controlador.obtenerSinonimosDe(texto);
                    long deltaT = System.nanoTime() - t0;
                    this.jTextFieldTipoBusqueda.setText("ms: " + ((double)deltaT / 1000000));
                    
                    if (sinonimos == null || sinonimos.size() == 0) {
                        JOptionPane.showMessageDialog(this, "No hay sinonimos para '" + texto + "' en el diccionario.");
                        sinonimosListModel.removeAllElements();
                        return;
                    }

                    sinonimosListModel.removeAllElements();
                    for (String sinonimo : sinonimos) {
                        sinonimosListModel.addElement(sinonimo);
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }//GEN-LAST:event_jTextFieldPalabraKeyPressed

    private void jButtonAplicarAlgoritmoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAplicarAlgoritmoActionPerformed
        Cursor oldCursor = getCursor();
        
        try {
            AlgoritmoHash algoritmoElegido =  ((AlgoritmoHash) jComboBoxAlgoritmoHash.getSelectedItem());
            String algoritmo = algoritmoElegido.clase;
            setCursor(new Cursor(Cursor.WAIT_CURSOR));
            long t0 = System.nanoTime();
            controlador.cambiarAlgoritmoHash(algoritmo);
            long deltaT = System.nanoTime() - t0;
            setCursor(oldCursor);

            diccionarioCambio = true;
            StringBuffer buffer = new StringBuffer();
            buffer.append("Tiempo en ms: " +((double)deltaT / 1000000) + "\n");
            buffer.append(controlador.obtenerResultadoReHash());
            
            JDialog dialog = new JDialog();
            dialog.getContentPane().add(new PanelResultadoAplicarAlgoritmo(buffer.toString()));
            dialog.setTitle("Resultado de aplicar " + algoritmoElegido.nombre);
            dialog.setResizable(false);
            dialog.pack();
            dialog.setVisible(true);
        } catch (ClassNotFoundException ex) {
            setCursor(oldCursor);
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "Algoritmo no reconocido.");
        } catch (Exception ex) {
            setCursor(oldCursor);
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "Error no experado al aplicar algoritmo.");
            resetPanel();
        }
    }//GEN-LAST:event_jButtonAplicarAlgoritmoActionPerformed

    private void jButtonPalabraAgregarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPalabraAgregarActionPerformed
        this.sinonimosListModel.removeAllElements();    
        String palabra = this.jTextFieldPalabra.getText().trim();
        if (palabra.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Debe ingresar una palabra para agregar al diccionario.");
            this.jTextFieldPalabra.requestFocusInWindow();
            return;
        }

        if (controlador.existePalabra(palabra)) {
            JOptionPane.showMessageDialog(this, "La palabra ya existe en el diccionario.");
            this.jTextFieldPalabra.setSelectionStart(0);
            this.jTextFieldPalabra.setSelectionEnd(palabra.length());
            this.jTextFieldPalabra.requestFocusInWindow();
            return;
        }

        agregarSinonimos(palabra);
        diccionarioCambio = true;
    }//GEN-LAST:event_jButtonPalabraAgregarActionPerformed

    private void jButtonPalabraEliminarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPalabraEliminarActionPerformed
            this.sinonimosListModel.removeAllElements();
            String palabra = this.jTextFieldPalabra.getText().trim();
            if (palabra.isEmpty()) {
                JOptionPane.showMessageDialog(this, "Debe ingresar una palabra a eliminar del diccionario.");
                this.jTextFieldPalabra.requestFocusInWindow();
                return;
            }

            if (!controlador.existePalabra(palabra)) {
                JOptionPane.showMessageDialog(this, "La palabra no existe en el diccionario.");
                this.jTextFieldPalabra.setSelectionStart(0);
                this.jTextFieldPalabra.setSelectionEnd(palabra.length());
                this.jTextFieldPalabra.requestFocusInWindow();
                return;
            }

            try {
                controlador.removerPalabra(palabra);
                diccionarioCambio = true;
                JOptionPane.showMessageDialog(this, "Se elimino la palabra del diccionario.");
                this.jTextFieldPalabra.setText("");
                this.jTextFieldPalabra.requestFocusInWindow();
            } catch (Exception ex) {                                                      
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "Error no experado al remover la palabra.");
                resetPanel();
            }
    }//GEN-LAST:event_jButtonPalabraEliminarActionPerformed

    private void jButtonSinonimoAgregarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSinonimoAgregarActionPerformed
        String palabra = this.jTextFieldPalabra.getText().trim();
        if (palabra.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Debe ingresar una palabra.");
            this.jTextFieldPalabra.requestFocusInWindow();
            return;
        }

        agregarSinonimos(palabra);
        diccionarioCambio = true;
    }//GEN-LAST:event_jButtonSinonimoAgregarActionPerformed

    private void jButtonSinonimoEliminarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSinonimoEliminarActionPerformed
       String palabra = this.jTextFieldPalabra.getText().trim();
        if (palabra.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Ingrese una palabra.");
            this.jTextFieldPalabra.requestFocusInWindow();
            return;
        }

        int idx = this.jListSinonimos.getSelectedIndex();
        if (idx < 0) {
            JOptionPane.showMessageDialog(this, "Debe seleccionar un sinonimo de la lista.");
            this.jListSinonimos.requestFocusInWindow();
            return;
        }

        String sinonimo = (String) sinonimosListModel.getElementAt(idx);
       
        try {
            controlador.removerSinonimoDe(palabra, sinonimo);
            sinonimosListModel.removeElement(sinonimo);
            diccionarioCambio = true;
        } catch(Exception ex) {
            JOptionPane.showMessageDialog(this, "Error no esperado al eliminar sinonimo.");
            this.jListSinonimos.requestFocusInWindow();            
        }
    }//GEN-LAST:event_jButtonSinonimoEliminarActionPerformed

    private void jButtonAdministradorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAdministradorActionPerformed
        if(administradorHabilitado) {
            administradorHabilitado = false; 
            this.jButtonPalabraAgregar.setEnabled(false);
            this.jButtonPalabraEliminar.setEnabled(false);
            this.jButtonSinonimoAgregar.setEnabled(false);
            this.jButtonSinonimoEliminar.setEnabled(false);            
            this.jComboBoxAlgoritmoHash.setEnabled(false);
            this.jButtonAplicarAlgoritmo.setEnabled(false);
            this.jButtonAdministrador.setText("Habilitar Administrador");
            return;
        }

        JOptionPane optionPane = new JOptionPane();
        final JDialog dialog = optionPane.createDialog(this, "Habilitar Administrador");       
        PanelContrasena panel = new PanelContrasena();
        panel.addComponentListener(new ComponentListener(){
            public void componentResized(ComponentEvent arg0) {
            }
           public void componentMoved(ComponentEvent arg0) {
            }
            public void componentShown(ComponentEvent arg0) {
            }
            public void componentHidden(ComponentEvent arg0) {
                dialog.setVisible(false);
            }
        });
        
        dialog.setContentPane(panel);
        dialog.pack();
        dialog.setVisible(true);
        
        if(panel.habilitarUsuario()) {
            administradorHabilitado = true;
            this.jTextFieldPalabra.setEnabled(true);
            this.jListSinonimos.setEnabled(true);
            this.jButtonGuardarDiccionario.setEnabled(true);
            this.jButtonPalabraAgregar.setEnabled(true);
            this.jButtonPalabraEliminar.setEnabled(true);
            this.jComboBoxAlgoritmoHash.setEnabled(true);
            this.jButtonAplicarAlgoritmo.setEnabled(true);
            this.jButtonAdministrador.setText("Deshabilitar Administrador");
        } else {
            administradorHabilitado = false;    
            this.jButtonAdministrador.setText("Habilitar Administrador");            
        }
        
        dialog.setVisible(false);
        dialog.dispose();
    }//GEN-LAST:event_jButtonAdministradorActionPerformed

    private void jButtonAbrirDiccionarioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAbrirDiccionarioActionPerformed
        Cursor oldCursor = getCursor(); 
        
        try { 
             resetPanel();
             setCursor(new Cursor(Cursor.WAIT_CURSOR));
             this.controlador.cargarDesdeArchivoSerializable();
             setCursor(oldCursor);
             JOptionPane.showMessageDialog(this, "Diccionario fue cargado correctamente.");
             
             if(administradorHabilitado) {
                 this.jButtonPalabraAgregar.setEnabled(true);
                 this.jButtonPalabraEliminar.setEnabled(true);
                 this.jComboBoxAlgoritmoHash.setEnabled(true);
                 this.jButtonAplicarAlgoritmo.setEnabled(true);
             }
            
             this.jTextFieldPalabra.setEnabled(true);
             this.jListSinonimos.setEnabled(true);                
             this.jButtonGuardarDiccionario.setEnabled(true);
             this.jButtonListar.setEnabled(true);
             this.jButtonAbrirDiccionario.setEnabled(true);
             this.jTextFieldPalabra.requestFocusInWindow();
             IHashCodeStrategy algoritmoSeteado = controlador.obtenerAlgoritmoHash();
             for(int i = 0; i < this.algoritmosHash.length; i++) {
                 AlgoritmoHash algoritmo = algoritmosHash[i];
                 if(algoritmo.clase.equals(algoritmoSeteado.getClass().getName())) {
                    this.jComboBoxAlgoritmoHash.setSelectedItem(algoritmo);
                 };
             }
         } catch (Exception io) {
             setCursor(oldCursor);
             String msg = io.getMessage();
             JOptionPane.showMessageDialog(this, "No se pudo cargar el diccionario." + (msg == null ? "" : "\nRazon: " + msg));
             resetPanel();
         }
    }//GEN-LAST:event_jButtonAbrirDiccionarioActionPerformed

    private void jButtonGuardarDiccionarioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGuardarDiccionarioActionPerformed
        controlador.guardarEnSerializable();
        diccionarioCambio = false;
    }//GEN-LAST:event_jButtonGuardarDiccionarioActionPerformed

    private void jButtonListarDiccionarioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonListarDiccionarioActionPerformed
        Cursor oldCursor = getCursor();
        
        try{
            TreeMap<String,List<String>> listaLexicograficaTreeMap = controlador.lista();    		
            PanelListado panel = new PanelListado();
            setCursor(new Cursor(Cursor.WAIT_CURSOR));
            panel.cargarTree( listaLexicograficaTreeMap );
            setCursor(oldCursor);
            panel.showList();
    	}catch(Exception ex){
            setCursor(oldCursor);
            String msg = ex.getMessage();
             JOptionPane.showMessageDialog(this, "No se pudo listar lexicograficamente el Diccionario." + (msg == null ? "" : "\nRazon: " + msg));
             resetPanel();
    	}
    }//GEN-LAST:event_jButtonListarDiccionarioActionPerformed

    private void jButtonAyudaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAyudaActionPerformed
        if(ayudaFrame != null) {
            ayudaFrame.dispose();
        }

        ayudaFrame = new JFrame("Ayuda");
        ayudaFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        ayudaFrame.getContentPane().add(new PanelAyuda());
        ayudaFrame.pack();
        GuiUtils.centrarEnPantalla(ayudaFrame);
        ayudaFrame.setVisible(true);
    }//GEN-LAST:event_jButtonAyudaActionPerformed
        
    private void resetPanel() {
        if(administradorHabilitado) {
            this.jButtonPalabraAgregar.setEnabled(true);
            this.jButtonPalabraEliminar.setEnabled(true);
            this.jComboBoxAlgoritmoHash.setEnabled(true);
            this.jButtonAplicarAlgoritmo.setEnabled(true);         
        } else {
            this.jButtonPalabraAgregar.setEnabled(false);
            this.jButtonPalabraEliminar.setEnabled(false);
            this.jButtonSinonimoAgregar.setEnabled(false);
            this.jButtonSinonimoEliminar.setEnabled(false);            
            this.jComboBoxAlgoritmoHash.setEnabled(false);
            this.jButtonAplicarAlgoritmo.setEnabled(false);            
        }
        
        this.jTextFieldPalabra.setEnabled(false);
        this.jListSinonimos.setEnabled(false);
        this.jButtonAbrirDiccionario.setEnabled(false);
        this.jButtonListar.setEnabled(false);
        this.jTextFieldPalabra.setText("");
        this.sinonimosListModel.removeAllElements();
        this.jButtonAbrirDiccionario.requestFocusInWindow();                
    }

    /**
     * Metodo del IControladorObserver que se llama cada vez que el controlador observa que
     * el diccionario cambio.
     * 
     * @param estado estado del diccionario.
     */
    public void update(String estado) {
        this.jTextFieldEstadoDiccionario.setText(estado);
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAbrirDiccionario;
    private javax.swing.JButton jButtonAdministrador;
    private javax.swing.JButton jButtonAplicarAlgoritmo;
    private javax.swing.JButton jButtonAyuda;
    private javax.swing.JButton jButtonGuardarDiccionario;
    private javax.swing.JButton jButtonListar;
    private javax.swing.JButton jButtonNuevoDesdeArchivo;
    private javax.swing.JButton jButtonPalabraAgregar;
    private javax.swing.JButton jButtonPalabraEliminar;
    private javax.swing.JButton jButtonSinonimoAgregar;
    private javax.swing.JButton jButtonSinonimoEliminar;
    private javax.swing.JComboBox jComboBoxAlgoritmoHash;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JList jListSinonimos;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanelABM;
    private javax.swing.JPanel jPanelDatos;
    private javax.swing.JScrollPane jScrollPaneSinonimos;
    private javax.swing.JTextField jTextFieldEstadoDiccionario;
    private javax.swing.JTextField jTextFieldPalabra;
    private javax.swing.JTextField jTextFieldTipoBusqueda;
    // End of variables declaration//GEN-END:variables

    public void windowOpened(WindowEvent arg0) {
    }

    public void windowClosing(WindowEvent arg0) {
        if(diccionarioCambio) {
            int result = JOptionPane.showConfirmDialog(this, "Hay cambios sin guardar. ¿Desea guardarlos ahora?", "Guardar cambios", JOptionPane.YES_NO_OPTION);
            
            if(result == JOptionPane.YES_OPTION) {
                controlador.guardarEnSerializable();
            }
        }
    }

    public void windowClosed(WindowEvent arg0) {
    }

    public void windowIconified(WindowEvent arg0) {
    }

    public void windowDeiconified(WindowEvent arg0) {
    }

    public void windowActivated(WindowEvent arg0) {
    }

    public void windowDeactivated(WindowEvent arg0) {
    }
}
